// SPDX-License-Identifier: GPL-2.0
/*
 * BiscuitOS SPECIAL DEVICE PAGE on GUP
 *
 * (C) 2024.04.10 BuddyZhang1 <buddy.zhang@aliyun.com>
 * (C) 2024.04.10 BiscuitOS
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

#define DEV_PATH		"/dev/BiscuitOS"
#define P2P_MMIO_BASE		0x200000000
#define P2P_MMIO_SIZE		0x100000 /* 1MB */
#define MAP_SIZE		P2P_MMIO_SIZE
#define FILE_PATH		"/mnt/ext4/BiscuitOS.txt"
#define O_DIRECT		00040000

int main()
{
	int fd, dfd;
	void *buffer;

	/* open device */
	fd = open(DEV_PATH, O_RDWR);
	if (fd < 0) {
		printf("ERROR: Can't open %s\n", DEV_PATH);
		return -1;
	}

	/* MMAP */
	buffer = mmap(NULL, MAP_SIZE,
		      PROT_READ | PROT_WRITE,
		      MAP_SHARED,
		      fd,
		      P2P_MMIO_BASE);
	if (buffer == MAP_FAILED) {
		printf("ERROR: MAP_FAILED.\n");
		close(fd);
		return -1;
	}

	/* FORBIDDEN ACCESS FAKE MMIO */

	/* WRITE OPS TEST */
	write(fd, buffer, 10);

	/* DIRECTIO */
	dfd = open(FILE_PATH, O_RDWR | O_DIRECT);
	if (dfd < 0) {
		printf("ERROR: Direct IO File.\n");
		munmap(buffer, MAP_SIZE);
		close(fd);
		return -1;
	}

	/* DIRECTIO Write */
	if (write(dfd, buffer, 4096) < 0) {
		BiscuitOS_memory_fluid_disable();
		printf("ERROR: Write FILE FAILED.\n");
		munmap(buffer, MAP_SIZE);
		close(fd);
		close(dfd);
		return -1;
	}
	
	/* RECLAIM */
	munmap(buffer, MAP_SIZE);
	close(dfd);
	close(fd);

	printf("TEST SUCCED.\n");

	return 0;
}
